﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RestaurantTabletApplication
{
    public partial class TableView : Form
    {
        private const int PollingInterval = 2 * 1000;

        private string tableNumber;
        private RestaurantWebService service;
        private OrderManager orderManager;
        private Timer pollingTimer;

        private IDictionary<String, GroupBox> tableColormapping;
        private IDictionary<String, Image> vacantOccupiedMapping, occupiedOrderingMapping, occupiedEatingMapping,
                                          orderingOccupiedMapping, eatingVacantMapping;

        private IDictionary<string, Meal> mealMap;
        private IDictionary<string, Order> orderMap;
        private string currentChair;
               
        public TableView(String tableNumber, RestaurantWebService service)
        {
            this.tableNumber = tableNumber;
            this.service = service;
            orderManager = new OrderManager();
            mealMap = new Dictionary<string, Meal>();
            orderMap = new Dictionary<string, Order>();

            InitializeComponent();
            InitializeTableDictionary();
            InitializeVacantOccupiedMapping();
            InitializeOccupiedOrderingMapping();
            InitializeOccupiedEatingMapping();
            InitializeOrderingOccupiedMapping();
            InitializeEatingVacantMapping();

            InitializePollingTimer();
            InitializeMenuData();
            InitializeSummaryData();
            InitializeStatusData();

            GroupBox tableGroupBox = tableColormapping[tableNumber];
            tableGroupBox.Visible = true;
        }

        private void InitializePollingTimer()
        {
            pollingTimer = new Timer();
            pollingTimer.Interval = PollingInterval;
            pollingTimer.Tick += UpdateStatusData;
            pollingTimer.Start();
        }

        private void InitializeMenuData()
        {
            menuView.View = View.Details;
            menuView.GridLines = true;
            menuView.FullRowSelect = true;
            menuView.CheckBoxes = true;
            menuView.Columns.Add("ID", 25);
            menuView.Columns.Add("Name", 100);
            menuView.Columns.Add("Cook Time", 100);
            menuView.Columns.Add("Price", 100);
            menuView.Columns.Add("Availability", 100);            
        }

        private void InitializeSummaryData()
        {
            summaryView.View = View.Details;
            summaryView.GridLines = true;
            summaryView.Columns.Add("Item", 100);
            summaryView.Columns.Add("Quantity", 75);
            summaryView.Columns.Add("@", 50);
            summaryView.Columns.Add("Price", 50);
        }

        private void InitializeStatusData()
        {
            statusView.View = View.Details;
            statusView.GridLines = true;
            statusView.Columns.Add("Seat", 50);
            statusView.Columns.Add("Meal", 100);
            statusView.Columns.Add("Status", 100);
        }

        private void InitializeTableDictionary()
        {
            tableColormapping = new Dictionary<String, GroupBox>() {
                {"01", table1_view}, {"02", table2_view}, {"03", table3_view}, 
                {"04", table4_view}, {"05", table5_view}, {"06", table6_view}, 
                {"07", table7_view}, {"08", table8_view}, {"09", table9_view}, 
                {"10", table10_view}, {"11", table11_view}, {"12", table12_view},
                {"13", table13_view}, {"14", table14_view}, {"15", table15_view}
            };
        }

        private void InitializeVacantOccupiedMapping()
        {
            vacantOccupiedMapping = new Dictionary<string, Image>() {
                {"y00", RestaurantTabletApplication.Properties.Resources.c_g00},
                {"y01", RestaurantTabletApplication.Properties.Resources.c_g01},
                {"y02", RestaurantTabletApplication.Properties.Resources.c_g02},
                {"y03", RestaurantTabletApplication.Properties.Resources.c_g03},
                {"y04", RestaurantTabletApplication.Properties.Resources.c_g04},
                {"y05", RestaurantTabletApplication.Properties.Resources.c_g05},
                {"y06", RestaurantTabletApplication.Properties.Resources.c_g06},
                {"y07", RestaurantTabletApplication.Properties.Resources.c_g07},
                {"y08", RestaurantTabletApplication.Properties.Resources.c_g08},
                {"y09", RestaurantTabletApplication.Properties.Resources.c_g09},
                {"y10", RestaurantTabletApplication.Properties.Resources.c_g10},
                {"y11", RestaurantTabletApplication.Properties.Resources.c_g11},
            };
        }

        private void InitializeOccupiedOrderingMapping()
        {
            occupiedOrderingMapping = new Dictionary<string, Image>() {
                {"g00", RestaurantTabletApplication.Properties.Resources.c_b00},
                {"g01", RestaurantTabletApplication.Properties.Resources.c_b01},
                {"g02", RestaurantTabletApplication.Properties.Resources.c_b02},
                {"g03", RestaurantTabletApplication.Properties.Resources.c_b03},
                {"g04", RestaurantTabletApplication.Properties.Resources.c_b04},
                {"g05", RestaurantTabletApplication.Properties.Resources.c_b05},
                {"g06", RestaurantTabletApplication.Properties.Resources.c_b06},
                {"g07", RestaurantTabletApplication.Properties.Resources.c_b07},
                {"g08", RestaurantTabletApplication.Properties.Resources.c_b08},
                {"g09", RestaurantTabletApplication.Properties.Resources.c_b09},
                {"g10", RestaurantTabletApplication.Properties.Resources.c_b10},
                {"g11", RestaurantTabletApplication.Properties.Resources.c_b11},
            };
        }
        
        private void InitializeOccupiedEatingMapping()
        {
            occupiedEatingMapping = new Dictionary<string, Image>() {
                {"g00", RestaurantTabletApplication.Properties.Resources.c_r00},
                {"g01", RestaurantTabletApplication.Properties.Resources.c_r01},
                {"g02", RestaurantTabletApplication.Properties.Resources.c_r02},
                {"g03", RestaurantTabletApplication.Properties.Resources.c_r03},
                {"g04", RestaurantTabletApplication.Properties.Resources.c_r04},
                {"g05", RestaurantTabletApplication.Properties.Resources.c_r05},
                {"g06", RestaurantTabletApplication.Properties.Resources.c_r06},
                {"g07", RestaurantTabletApplication.Properties.Resources.c_r07},
                {"g08", RestaurantTabletApplication.Properties.Resources.c_r08},
                {"g09", RestaurantTabletApplication.Properties.Resources.c_r09},
                {"g10", RestaurantTabletApplication.Properties.Resources.c_r10},
                {"g11", RestaurantTabletApplication.Properties.Resources.c_r11},
            };
        }


        private void InitializeOrderingOccupiedMapping()
        {
            orderingOccupiedMapping = new Dictionary<string, Image>() {
                {"b00", RestaurantTabletApplication.Properties.Resources.c_g00},
                {"b01", RestaurantTabletApplication.Properties.Resources.c_g01},
                {"b02", RestaurantTabletApplication.Properties.Resources.c_g02},
                {"b03", RestaurantTabletApplication.Properties.Resources.c_g03},
                {"b04", RestaurantTabletApplication.Properties.Resources.c_g04},
                {"b05", RestaurantTabletApplication.Properties.Resources.c_g05},
                {"b06", RestaurantTabletApplication.Properties.Resources.c_g06},
                {"b07", RestaurantTabletApplication.Properties.Resources.c_g07},
                {"b08", RestaurantTabletApplication.Properties.Resources.c_g08},
                {"b09", RestaurantTabletApplication.Properties.Resources.c_g09},
                {"b10", RestaurantTabletApplication.Properties.Resources.c_g10},
                {"b11", RestaurantTabletApplication.Properties.Resources.c_g11},
            };
        }


        private void InitializeEatingVacantMapping()
        {
            eatingVacantMapping = new Dictionary<string, Image>() {
                {"r00", RestaurantTabletApplication.Properties.Resources.c_y00},
                {"r01", RestaurantTabletApplication.Properties.Resources.c_y01},
                {"r02", RestaurantTabletApplication.Properties.Resources.c_y02},
                {"r03", RestaurantTabletApplication.Properties.Resources.c_y03},
                {"r04", RestaurantTabletApplication.Properties.Resources.c_y04},
                {"r05", RestaurantTabletApplication.Properties.Resources.c_y05},
                {"r06", RestaurantTabletApplication.Properties.Resources.c_y06},
                {"r07", RestaurantTabletApplication.Properties.Resources.c_y07},
                {"r08", RestaurantTabletApplication.Properties.Resources.c_y08},
                {"r09", RestaurantTabletApplication.Properties.Resources.c_y09},
                {"r10", RestaurantTabletApplication.Properties.Resources.c_y10},
                {"r11", RestaurantTabletApplication.Properties.Resources.c_y11},
            };
        }

        private void ServeChair(object sender, EventArgs e)
        {
            if (((PictureBox)sender).Tag.ToString().Contains("waiting")) //vacant
            {
                string chairName = ((PictureBox)sender).Tag.ToString().Replace("waiting_", "").Trim();
                ((PictureBox)sender).Image = vacantOccupiedMapping[chairName];
                ((PictureBox)sender).Tag = "occupied_g" + chairName.Substring(1,2);
            }
            else if (((PictureBox)sender).Tag.ToString().Contains("occupiedOrdered"))
            {
                string chairName = ((PictureBox)sender).Tag.ToString().Replace("occupiedOrdered_", "").Trim();
                ((PictureBox)sender).Image = occupiedEatingMapping[chairName];
                ((PictureBox)sender).Tag = "eating_r" + chairName.Substring(1, 2);

                service.acknowledgeDelivery(orderMap[chairName.Substring(1,2)]);
                UpdateStatusData(null, null);
            }
            else if (((PictureBox)sender).Tag.ToString().Contains("occupied"))
            {
                string chairName = ((PictureBox)sender).Tag.ToString().Replace("occupied_", "").Trim();
                ((PictureBox)sender).Image = occupiedOrderingMapping[chairName];
                ((PictureBox)sender).Tag = "ordering_b" + chairName.Substring(1, 2);

                currentChair = chairName.Substring(1, 2);
                PopulateMenu();
                menuView.ItemChecked += this.HandleMealSelection;
            }
            else if (((PictureBox)sender).Tag.ToString().Contains("ordering"))
            {
                string chairName = ((PictureBox)sender).Tag.ToString().Replace("ordering_", "").Trim();
                ((PictureBox)sender).Image = orderingOccupiedMapping[chairName];
                ((PictureBox)sender).Tag = "occupiedOrdered_g" + chairName.Substring(1, 2);

                menuView.ItemChecked -= this.HandleMealSelection;
                menuView.Items.Clear();
            }
            else if (((PictureBox)sender).Tag.ToString().Contains("eating"))
            {
                string chairName = ((PictureBox)sender).Tag.ToString().Replace("eating_", "").Trim();
                ((PictureBox)sender).Image = eatingVacantMapping[chairName];
                ((PictureBox)sender).Tag = "waiting_y" + chairName.Substring(1, 2);
            }            
        }

        private void UpdateSummary()
        {
            summaryView.Items.Clear();

            IDictionary<Meal, int> mealCountMap = new Dictionary<Meal, int>();
            foreach (KeyValuePair<string, Order> entry in orderMap)
            {
                Meal meal = entry.Value.Meal;
                int count;
                if (!mealCountMap.ContainsKey(meal))
                {
                    count = 0;
                }
                else
                {
                    count = mealCountMap[meal];
                }
                count++;
                mealCountMap[meal] = count;
            }

            float total = 0;
            ListViewItem item;
            foreach (KeyValuePair<Meal, int> entry in mealCountMap)
            {
                Meal meal = entry.Key;
                float price = entry.Value * meal.Price;
                total += price;
                item = new ListViewItem(new String[] {
                    meal.Name,
                    entry.Value.ToString(),
                    meal.Price.ToString(),
                    price.ToString()
                });
                summaryView.Items.Add(item);
            }
        }

        private void UpdateStatusData(object sender, EventArgs e)
        {
            statusView.Items.Clear();

            Order[] activeOrders = service.getActiveOrders(int.Parse(tableNumber));
            ListViewItem activeOrder;
            foreach (Order order in activeOrders)
            {
                activeOrder = new ListViewItem(new string[] { 
                    order.SeatNumber.ToString(),
                    order.Meal.Name, 
                    order.Status.ToString()
                });

                statusView.Items.Add(activeOrder);
            }
        }

        private void PopulateMenu()
        {
            List<Meal> items = ClientMenu.Instance.Meals;            
            ListViewItem item;
            foreach (Meal meal in items) 
            {
                item = new ListViewItem(new string[] { 
                    meal.MealNumber.ToString(),
                    meal.Name, 
                    meal.TimeToProduce.ToString(),
                    meal.Price.ToString(),
                    meal.IsAvailable.ToString()
                });

                menuView.Items.Add(item);
            }
         }

        private void HandleMealSelection(Object sender, EventArgs e)
        {
            ListView menu = (ListView) sender;
            IEnumerable<ListViewItem> enumerable = menu.CheckedItems.Cast<ListViewItem>();
            if (enumerable.Count() > 0)
            {
                ListViewItem selectedMenu = enumerable.First();
                int selectedMealNumer = int.Parse(selectedMenu.SubItems[0].Text);
                Meal meal = ClientMenu.Instance.getMealByNumber(selectedMealNumer);
                mealMap[currentChair] = meal;
            }
            else
            {
                mealMap.Remove(currentChair);
            }
        }

        private void SendOrders(object sender, EventArgs e)
        {
            IList<Order> orders = new List<Order>();
            foreach (KeyValuePair<string, Meal> entry in mealMap)
            {
                string seatNumber = entry.Key;

                Order newOrder = new Order();
                newOrder.TableNumber = int.Parse(tableNumber);
                newOrder.SeatNumber = int.Parse(seatNumber);
                newOrder.WaiterName = "Uchi";
                newOrder.Meal = entry.Value;
                newOrder.OrderNumber = service.placeOrder(newOrder);
                orderManager.placeOrder(newOrder);
                orderMap.Add(seatNumber, newOrder);
            }
            mealMap.Clear();
            UpdateSummary();
            UpdateStatusData(null, null);
        }

        private void OnClickRestaurantViewButton(object sender, EventArgs e)
        {
            Close();
        }   
    }
}
